#include "duallist.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct _tag_DualLink _DualLink;

struct _tag_DualLink{
    DualLinkNode head;//因为是header ，所以需要维护实体
    DualLinkNode* slider; //因为只是一个游标，所以只需要指针
    int length;
};


DualLink* DualLink_Create(){
    _DualLink* list=(_DualLink*)malloc(sizeof (_DualLink));
    if(list==NULL){
        perror("error occure while malloc for Duallist");
    }
    memset(list,0,sizeof (_DualLink));
    list->head.next=NULL;
    list->slider==NULL;
    return list;
}

void DualLink_Destroy(DualLink *list){
    if(list==NULL){
        perror("dual list can not be null");
        return ;
    }
    _DualLink* tmp=NULL;
    tmp=list;
    free(tmp);
}

void DualLink_Clear(DualLink* list){
    if(list==NULL){
        perror("dual list can not be null");
        return ;
    }
    _DualLink* tmp=NULL;
    tmp=list;
    tmp->head.next=NULL;
    tmp->length=0;
    tmp->slider=NULL;
}

int DualLink_Length(DualLink* list){
    if(list==NULL){
        perror("dual list can not be null");
        return -1;
    }
    _DualLink* tmp=NULL;
    tmp=list;
    return tmp->length;
}

int DualLink_Insert(DualLink* list,DualLinkNode* node,int pos){
    //
    if(list==NULL){
        perror("dual list can not be null");
    }
    _DualLink* tmp=NULL;
    tmp=list;
    // 0 1 2  不能超过长度3 即使,其实也可以不用限制长度，只要走到最后
    if(pos<0){
        perror("pos is invalid!");
        return -2;
    }
    DualLinkNode* current=NULL;
    current=&(tmp->head);
    for(int i=0;i<pos&&current->next!=NULL;i++){
        current=current->next;
    }
    //0 1 2 3 4 5
    //		|
    //首先当前指向新,新指向后
    //后反指新，新反指当前
    DualLinkNode* nextNode=NULL;
    nextNode=current->next;

    current->next=node;			//1 后
    node->next=nextNode;	//2后
    //当插入第一个元素的时候？head.next==NULL

    //如果nextNode为NULL,那么基点node->next=NULL
    if(nextNode!=NULL){
        nextNode->prev=node;	//3前
    }
    //如果当前节点是head 节点
    if(current==&(tmp->head)){
        node->prev=NULL;
        tmp->slider=node;
    }else{
        node->prev=current; //2 前
    }
    tmp->length++;
    return 0;
}

DualLinkNode *DualLink_Get(DualLink* list,int pos){
    if(list==NULL) {
            perror("dual list can not be null");
    }
    _DualLink* tmp=NULL;
    tmp=list;
    // 0 1 2  不能超过长度3 即使,其实也可以不用限制长度，只要走到最后
    if(pos<0||pos>tmp->length){
        perror("pos is invalid!");
        return -2;
    }
    DualLinkNode* current=NULL;
    current=&(tmp->head);
    for(int i=0;i<pos&&current->next!=NULL;i++){
        current=current->next;
    }
    return current->next;
}

DualLinkNode *DualLink_Delete(DualLink* list,int pos){
    if(list==NULL) {
            perror("dual list can not be null");
    }
    _DualLink* tmp=NULL;
    tmp=list;
    // 0 1 2  不能超过长度3 即使,其实也可以不用限制长度，只要走到最后
    if(pos<0||pos>=tmp->length){
        perror("pos is invalid!");
        return -2;
    }
    DualLinkNode* current=NULL;
    current=&(tmp->head);
    for(int i=0;i<pos&&current->next!=NULL;i++){
        current=current->next;
    }
    //1 2 3 NULL
    DualLinkNode* deleteNode= current->next;
    DualLinkNode* afterDeleteNode= deleteNode->next;
    if(afterDeleteNode!=NULL){
        //如果删除的是第一个节点
        if(current==&(tmp->head)){
            afterDeleteNode->prev=NULL;
        }else{
            afterDeleteNode->prev=current;
        }
    }
    current->next=afterDeleteNode;
    tmp->length--;
    if(tmp->slider==deleteNode){
        tmp->slider=tmp->head.next;
    }
    return deleteNode;
}

DualLinkNode *DualLink_Current(DualLink* list){
    if(list==NULL){
        perror("dual list can not be null");
        return -1;
    }
    _DualLink* tmp=NULL;
    tmp=list;
    return tmp->slider;
}

DualLinkNode *DualLink_Reset(DualLink* list){
    if(list==NULL){
        perror("dual list can not be null");
        return -1;
    }
    _DualLink* tmp=NULL;
    tmp=list;
    tmp->slider=tmp->head.next;
    return tmp->slider;
}

DualLinkNode *DualLink_Next(DualLink* list){
    if(list==NULL){
        perror("dual list can not be null");
        return -1;
    }
    _DualLink* tmp=NULL;
    tmp=list;
    if(tmp->slider!=NULL){
        tmp->slider=tmp->slider->next;
    }
    return tmp->slider;
}

DualLinkNode *DualLink_Prev(DualLink* list){
    if(list==NULL){
        perror("dual list can not be null");
        return -1;
    }
    _DualLink* tmp=NULL;
    tmp=list;
    if(tmp->slider!=NULL){
        if(tmp->slider->prev!=NULL){
            tmp->slider=tmp->slider->prev;
        }
    }
    return tmp->slider;
}

DualLinkNode *DualLink_DeleteNode(DualLink* list,DualLinkNode *node){

    if(list==NULL){
        perror("dual list can not be null");
        return -1;
    }
    _DualLink* tmp=NULL;
    tmp=list;
    DualLinkNode* current=NULL;
    DualLinkNode* find=NULL;
    int npos;
    current=&(tmp->head);
    for(int i=0;i<tmp->length;i++){
        if(current->next==node){
            npos=i;
            find=current->next;
            break;
        }
        current=current->next;
    }
    if(find!=NULL){
        DualLink_Delete(list,npos);
    }
    return find;
}
